上一章有提到,List 比 Array 更有彈性。與 Array 不同的是,List 可以明確地選擇是不可變的 List 或是可改的 MutableList。不過,List 也有缺點,就是 List 允許重複的內容。假如今天你需要一個會員清單,這個清單的內容是不能重複時,List 就沒辦法滿足需求。好在 Kotlin Collection 還有其他的選擇,這一章就要來介紹 Set。
Set
是一個沒有順序、沒有重複值的集合。除了這兩點外,其他特質都跟 List 差距不大。Set 跟 List 一樣有兩種,一種是不能改變大小及內容的 Set
、一種是可以改變大小及內容的 MutableSet
。
宣告 Set 很簡單,Kotlin 標準函式庫提供了兩個函數 setOf()
用來宣告一個靜態的 Set、mutableSetOf()
用來宣告一個動態的 Set。
val setOfNames = setOf("Jim", "Sue", "Sue", "Nick", "Nick") // 只存放不重複的 Jim, Sue, Nick
val mutableSetOfNames = mutableSetOf("Jim", "Sue", "Sue", "Nick", "Nick") // 只存放不重複的 Jim, Sue, Nick
透過 Kotlin 的型別推斷,setOfNames
的型別就會是 Set<String>
、mutableSetOfNames
的型別則會是 MutableSet<String>
。要注意的是,Set 會自動把重複的內容過濾掉,所以上面的範例放入 5 個名字,但只會存入不重複的 3 個名字。
假如今天需要宣告一個空的 Set 或 MutableSet,則有幾種可行的作法:
val emptySet = setOf<String>()
val emptyMutableSet = mutableSetOf<String>()
val emptySetByEmptySet = emptySet<String>()
要注意的是,Set 是無序的,所以跟 Array 或 List 不同,它本身沒有 index。換言之,我們沒有辦法用索引值來取出其中的資料。不過,Kotlin 仍有提供類似 get()
的方法來取出資料,這個方法是 elementAt()
;或是我們只能用迴圈來取出所有資料。
val secondName = setOfNames.elementAt(1) // 取得放在第 2 格的元素
for (name in setOfNames) {
println(name) // 會一行一行印出 Jim Sue Nick
}
我們也可以用 Set 的屬性或方法來取得 Set 的資訊,或是做資料處理:
val setOfNumbers = setOf(2, 3, 3, 6, 7, 10)
val size = setOfNumbers.size // 以屬性取得 Set 的大小
val sum = setOfNumbers.sum() // 計算出 Set 裡所有數字的總合
val average = setOfNumbers.average() // 計算出 Set 裡所有數字的平均值
val min = setOfNumbers.minOrNull() // 取出 Set 裡的最小值或 Null
val max = setOfNumbers.maxOrNull() // 取出 Set 裡的最大值或 Null
簡單的說,Set 就是不在意順序、也不會重覆的 List。在使用時要抓緊這個特色,甚至可以利用這個特性讓 List 轉成 Set 來過濾重複的資料,這些技巧會在後續的章節做深入討論。下一個章節我們要討論 Kotlin Collection 的最後一個類別 Map
。